/************************************************************************************************* 

	Name: BUMPERS_H
	Autor: JA&AP
	
	Contains: 
				File containing all the functions related to the Bumpers hardware.
				
				
**************************************************************************************************/

#include "bumpers.h"
#include <avr/io.h>
#include <avr/interrupt.h>

#define DDR_BMP_FLEFT DDRC
#define DDR_BMP_FRIGHT DDRC
#define DDR_BMP_BLEFT DDRC
#define DDR_BMP_BRIGHT DDRC

#define PORT_BMP_FLEFT PORTC
#define PORT_BMP_FRIGHT PORTC
#define PORT_BMP_BLEFT PORTC
#define PORT_BMP_BRIGHT PORTC

#define PORTPIN_BMP_FLEFT PINC
#define PORTPIN_BMP_FRIGHT PINC
#define PORTPIN_BMP_BLEFT PINC
#define PORTPIN_BMP_BRIGHT PINC

#define PIN_BMP_FLEFT PC0
#define PIN_BMP_FRIGHT PC1
#define PIN_BMP_BLEFT PC2
#define PIN_BMP_BRIGHT PC3

#define BMP_INT_EN PCIE0
#define BMP_INT_PIN PCINT4

static unsigned char bumpersState;

static unsigned char bumpers_getState(void){

	return (PORTPIN_BMP_FLEFT & (1<<PIN_BMP_FLEFT)) | (PORTPIN_BMP_FRIGHT & (1<<PIN_BMP_FRIGHT)) | (PORTPIN_BMP_BLEFT & (1<<PIN_BMP_BLEFT)) | (PORTPIN_BMP_BRIGHT & (1<<PIN_BMP_BRIGHT));
}

unsigned char bumpers_read()
{
	return bumpersState;
}

//Configura los pines de los bumpers como entrada, y configura la Pin Change Interrupt. Esta se activa si existe algun cambio de nivel en el pin configurado para tal fin. Solo accede a la interrupcion en los flancos, no se queda metido en la interrupcion porq no trabaja por nivel.

void bumpers_init(){

	//Setting Bumper Pins as input
	DDR_BMP_FLEFT &= ~(1<<PIN_BMP_FLEFT);
	DDR_BMP_FRIGHT &= ~(1<<PIN_BMP_FRIGHT);
	DDR_BMP_BLEFT &= ~(1<<PIN_BMP_BLEFT);
	DDR_BMP_BRIGHT &= ~(1<<PIN_BMP_BRIGHT);

	//Configuration of Interrupt
	PCICR |= (1<<BMP_INT_EN);
	PCMSK0 |= (1<<BMP_INT_PIN);
}

ISR(PCINT0_vect)
{
	bumpersState = bumpers_getState();
}
